package javax.mail;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.BitSet;
import java.util.Locale;

public class URLName {
    private static boolean doEncode;
    static BitSet dontNeedEncoding = new BitSet(256);
    private String file;
    protected String fullURL;
    private int hashCode = 0;
    private String host;
    private InetAddress hostAddress;
    private boolean hostAddressKnown = false;
    private String password;
    private int port = -1;
    private String protocol;
    private String ref;
    private String username;

    static {
        int i;
        boolean z = true;
        doEncode = true;
        try {
            if (Boolean.getBoolean("mail.URLName.dontencode")) {
                z = false;
            }
            doEncode = z;
        } catch (Exception e) {
        }
        for (i = 97; i <= 122; i++) {
            dontNeedEncoding.set(i);
        }
        for (i = 65; i <= 90; i++) {
            dontNeedEncoding.set(i);
        }
        for (i = 48; i <= 57; i++) {
            dontNeedEncoding.set(i);
        }
        dontNeedEncoding.set(32);
        dontNeedEncoding.set(45);
        dontNeedEncoding.set(95);
        dontNeedEncoding.set(46);
        dontNeedEncoding.set(42);
    }

    public URLName(String protocol, String host, int port, String file, String username, String password) {
        this.protocol = protocol;
        this.host = host;
        this.port = port;
        if (file != null) {
            int refStart = file.indexOf(35);
            if (refStart != -1) {
                this.file = file.substring(0, refStart);
                this.ref = file.substring(refStart + 1);
                if (doEncode) {
                    username = encode(username);
                }
                this.username = username;
                if (doEncode) {
                    password = encode(password);
                }
                this.password = password;
            }
        }
        this.file = file;
        this.ref = null;
        if (doEncode) {
            username = encode(username);
        }
        this.username = username;
        if (doEncode) {
            password = encode(password);
        }
        this.password = password;
    }

    public String toString() {
        if (this.fullURL == null) {
            StringBuffer tempURL = new StringBuffer();
            if (this.protocol != null) {
                tempURL.append(this.protocol);
                tempURL.append(":");
            }
            if (!(this.username == null && this.host == null)) {
                tempURL.append("//");
                if (this.username != null) {
                    tempURL.append(this.username);
                    if (this.password != null) {
                        tempURL.append(":");
                        tempURL.append(this.password);
                    }
                    tempURL.append("@");
                }
                if (this.host != null) {
                    tempURL.append(this.host);
                }
                if (this.port != -1) {
                    tempURL.append(":");
                    tempURL.append(Integer.toString(this.port));
                }
                if (this.file != null) {
                    tempURL.append("/");
                }
            }
            if (this.file != null) {
                tempURL.append(this.file);
            }
            if (this.ref != null) {
                tempURL.append("#");
                tempURL.append(this.ref);
            }
            this.fullURL = tempURL.toString();
        }
        return this.fullURL;
    }

    public int getPort() {
        return this.port;
    }

    public String getProtocol() {
        return this.protocol;
    }

    public String getFile() {
        return this.file;
    }

    public String getHost() {
        return this.host;
    }

    public String getUsername() {
        return doEncode ? decode(this.username) : this.username;
    }

    public String getPassword() {
        return doEncode ? decode(this.password) : this.password;
    }

    public boolean equals(Object obj) {
        if (!(obj instanceof URLName)) {
            return false;
        }
        URLName u2 = (URLName) obj;
        if (u2.protocol == null || !u2.protocol.equals(this.protocol)) {
            return false;
        }
        InetAddress a1 = getHostAddress();
        InetAddress a2 = u2.getHostAddress();
        if (a1 == null || a2 == null) {
            if (this.host == null || u2.host == null) {
                if (this.host != u2.host) {
                    return false;
                }
            } else if (!this.host.equalsIgnoreCase(u2.host)) {
                return false;
            }
        } else if (!a1.equals(a2)) {
            return false;
        }
        if (this.username != u2.username && (this.username == null || !this.username.equals(u2.username))) {
            return false;
        }
        if ((this.file == null ? "" : this.file).equals(u2.file == null ? "" : u2.file) && this.port == u2.port) {
            return true;
        }
        return false;
    }

    public int hashCode() {
        if (this.hashCode != 0) {
            return this.hashCode;
        }
        if (this.protocol != null) {
            this.hashCode += this.protocol.hashCode();
        }
        InetAddress addr = getHostAddress();
        if (addr != null) {
            this.hashCode += addr.hashCode();
        } else if (this.host != null) {
            this.hashCode += this.host.toLowerCase(Locale.ENGLISH).hashCode();
        }
        if (this.username != null) {
            this.hashCode += this.username.hashCode();
        }
        if (this.file != null) {
            this.hashCode += this.file.hashCode();
        }
        this.hashCode += this.port;
        return this.hashCode;
    }

    private synchronized InetAddress getHostAddress() {
        InetAddress inetAddress = null;
        synchronized (this) {
            if (this.hostAddressKnown) {
                inetAddress = this.hostAddress;
            } else if (this.host != null) {
                try {
                    this.hostAddress = InetAddress.getByName(this.host);
                } catch (UnknownHostException e) {
                    this.hostAddress = null;
                }
                this.hostAddressKnown = true;
                inetAddress = this.hostAddress;
            }
        }
        return inetAddress;
    }

    static String encode(String s) {
        if (s == null) {
            return null;
        }
        for (int i = 0; i < s.length(); i++) {
            int c = s.charAt(i);
            if (c == 32 || !dontNeedEncoding.get(c)) {
                return _encode(s);
            }
        }
        return s;
    }

    private static String _encode(String s) {
        StringBuffer out = new StringBuffer(s.length());
        ByteArrayOutputStream buf = new ByteArrayOutputStream(10);
        OutputStreamWriter writer = new OutputStreamWriter(buf);
        for (int i = 0; i < s.length(); i++) {
            int c = s.charAt(i);
            if (dontNeedEncoding.get(c)) {
                if (c == 32) {
                    c = 43;
                }
                out.append((char) c);
            } else {
                try {
                    writer.write(c);
                    writer.flush();
                    byte[] ba = buf.toByteArray();
                    for (int j = 0; j < ba.length; j++) {
                        out.append('%');
                        char ch = Character.forDigit((ba[j] >> 4) & 15, 16);
                        if (Character.isLetter(ch)) {
                            ch = (char) (ch - 32);
                        }
                        out.append(ch);
                        ch = Character.forDigit(ba[j] & 15, 16);
                        if (Character.isLetter(ch)) {
                            ch = (char) (ch - 32);
                        }
                        out.append(ch);
                    }
                    buf.reset();
                } catch (IOException e) {
                    buf.reset();
                }
            }
        }
        return out.toString();
    }

    static String decode(String s) {
        if (s == null) {
            return null;
        }
        if (indexOfAny(s, "+%") == -1) {
            return s;
        }
        StringBuffer sb = new StringBuffer();
        int i = 0;
        while (i < s.length()) {
            char c = s.charAt(i);
            switch (c) {
                case '%':
                    try {
                        sb.append((char) Integer.parseInt(s.substring(i + 1, i + 3), 16));
                        i += 2;
                        break;
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException();
                    }
                case '+':
                    sb.append(' ');
                    break;
                default:
                    sb.append(c);
                    break;
            }
            i++;
        }
        String result = sb.toString();
        try {
            result = new String(result.getBytes("8859_1"));
        } catch (UnsupportedEncodingException e2) {
        }
        return result;
    }

    private static int indexOfAny(String s, String any) {
        return indexOfAny(s, any, 0);
    }

    private static int indexOfAny(String s, String any, int start) {
        try {
            int len = s.length();
            for (int i = start; i < len; i++) {
                if (any.indexOf(s.charAt(i)) >= 0) {
                    return i;
                }
            }
            return -1;
        } catch (StringIndexOutOfBoundsException e) {
            return -1;
        }
    }
}
